﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Domain.Abstract;
using Domain.Entity;
using Domain.Concrete;
using Pro260Website.Models;
using Pro260Website.Infrastructure.Filters;
using System.IO;

namespace Pro260Website.Controllers
{
    public class PlatformController : Controller
    {
        private IPlatformRepository repository;
        private IVideoRepository repositoryVideo;

        private const int DEFAULT_PAGE_SIZE = 10;

        public PlatformController(IPlatformRepository platformRepository)
        {
            repository = platformRepository;
        }
        public PlatformController(IPlatformRepository platformRepository, IVideoRepository videoRepository)
        {
            repository = platformRepository;
            repositoryVideo = videoRepository;
        }

        public ViewResult Listings(string SearchField = "", int page = 1, int pageSize = DEFAULT_PAGE_SIZE)
        {
            var viewModel = GetViewModel(SearchField, page, pageSize);

            return View(viewModel);
        }

        [Authorize(Roles = "Admin")]
        public ViewResult AdminListings(string SearchField = "", int page = 1, int pageSize = DEFAULT_PAGE_SIZE)
        {
            var viewModel = GetViewModel(SearchField, page, pageSize);

            return View(viewModel);
        }

        private ListingViewModel<Platform> GetViewModel(string queryString, int page, int pageSize)
        {
            var items = repository.Platforms;

            if (!string.IsNullOrWhiteSpace(queryString))
            {
                items = items = repository.SearchPlatform(queryString).AsQueryable();
            }

            var viewModel = new ListingViewModel<Platform>()
            {
                Items = items.OrderBy(c => c.Name).Skip((page - 1) * pageSize).Take(pageSize),
                PagingInfo = new PagingInfo
                {
                    CurrentPage = page,
                    ItemsPerPage = pageSize,
                    TotalItems = items.Count()
                },
                QueryInfo = new QueryInfo
                {
                    QueryString = queryString
                }
            };

            return viewModel;
        }

        public ViewResult Platform(int platformID)
        {
            EntityViewModel<Platform> viewModel = new EntityViewModel<Platform>
            {
                Entity = repository.Platforms.FirstOrDefault(p => p.PlatformID == platformID)
            };

            return View(viewModel);
        }

        //CRUD
        [Authorize(Roles = "Admin")]
        public ViewResult CreatePlatform()
        {
            return View("EditPlatform", new Platform());
        }

        [HttpPost]
        [YoutubeLinkParse]
        [Authorize(Roles = "Admin")]
        public ActionResult EditPlatform(Platform entity, HttpPostedFileBase vidFile)
        {
            Video video = null;
            string path = "";

            if (vidFile != null)
            {
                if (vidFile.ContentLength > 0)
                {
                    var fileNameOriginal = Path.GetFileName(vidFile.FileName);
                    var pathTemp = Path.Combine(Server.MapPath(""), fileNameOriginal);
                    var fileExtension = Path.GetExtension(pathTemp);
                    if (fileExtension.Equals(".swf") || fileExtension.Equals(".wmv"))
                    {
                        bool nameExists = false;
                        var fileName = string.Empty;
                        while (true)
                        {
                            nameExists = false;
                            fileName = GenerateID() + fileExtension;

                            foreach (var v in repositoryVideo.Videos)
                            {
                                if (v.VideoName != null)
                                {
                                    if (v.VideoName.Equals(fileName))
                                    {
                                        nameExists = true;
                                    }
                                }
                            }
                            if (!nameExists)
                            {
                                break;
                            }
                        }
                        if (!nameExists)
                        {
                            if (fileExtension.Equals(".swf") || fileExtension.Equals(".wmv"))
                            {
                                path = Path.Combine(Server.MapPath("~/Content/Video"), fileName);
                            }

                            entity.VideoName = fileName;

                            video = new Video()
                            {
                                VideoName = fileName,
                                OriginalName = fileNameOriginal,
                                ExtensionType = fileExtension
                            };
                        }
                    }
                }
            }


            if (ModelState.IsValid)
            {
                if (vidFile != null)
                {
                    vidFile.SaveAs(path);
                    repositoryVideo.SaveVideo(video);
                }

                repository.SavePlatform(entity);
                return RedirectToAction("AdminListings");
            }
            else
            {
                return View(entity);
            }
        }

        [Authorize(Roles = "Admin")]
        public ViewResult EditPlatform(int platformID)
        {
            Platform platform = repository.Platforms.FirstOrDefault(p => p.PlatformID == platformID);
            return View(platform);
        }

        [Authorize(Roles = "Admin")]
        public ActionResult DeletePlatform(int platformID)
        {
            Platform platform = repository.Platforms.FirstOrDefault(p => p.PlatformID == platformID);
            if (platform != null)
            {
                repository.RemovePlatform(platform);
                TempData["message"] = string.Format("{0} was deleted", platform.Name);
            }
            else
            {
                TempData["message"] = string.Format("That platform isn't listed");
            }

            return RedirectToAction("AdminListings");
        }

        [Authorize(Roles = "Admin")]
        public ActionResult AddNews(int platformId)
        {
            var model = new PlatformNewsViewModel
            {
                PlatformId = platformId,
                Article = new PlatformNewsArticle
                {
                    PostedDate = DateTime.Now
                }
            };
            return View(model);
        }

        [HttpPost]
        [Authorize(Roles = "Admin")]
        public ActionResult AddNews(PlatformNewsViewModel model)
        {
            if (ModelState.IsValid)
            {

                var platform = repository.Platforms.FirstOrDefault(p => p.PlatformID == model.PlatformId);
                platform.Articles.Add(model.Article);
                repository.SavePlatform(platform);
                return RedirectToAction("AdminListings");
            }
            return View(model);
        }

        public FileContentResult GetImage(int id)
        {
            var game = repository.FindPlatform(id);
            if (game != null)
            {
                if (game.ImageData != null)
                    return File(game.ImageData, game.ImageMimeType);

                return null;
            }

            return null;
        }

        private string GenerateID()
        {
            Random random = new Random();
            string ID = "";
            for (int i = 0; i < 16; i++)
            {
                int num = random.Next(48, 58);
                int upper = random.Next(65, 91);
                int lower = random.Next(97, 123);

                int which = random.Next(3);
                if (which == 0)
                {
                    ID = ID + (char)num;
                }
                else if (which == 1)
                {
                    ID = ID + (char)upper;
                }
                else if (which == 2)
                {
                    ID = ID + (char)lower;
                }
            }

            return ID;
        }
    }
}
